package com.cgnpc.scp.purchase.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cgnpc.cuddemo.funcInstance.service.ICudFileService;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IBpmCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.common.exception.ScpException;
import com.cgnpc.scp.common.pojo.ActivityInfoParams;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.utils.BpmUtil;
import com.cgnpc.scp.common.utils.StringUtil;
import com.cgnpc.scp.purchase.mybatis.entity.*;
import com.cgnpc.scp.purchase.mybatis.mapper.client.*;
import com.cgnpc.scp.purchase.service.IChangeProcessService;
import com.cgnpc.scp.purchase.service.IPurchaseContractItemService;
import net.bytebuddy.asm.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/******************************
 * 用途说明: 调试采购-年度需求变更审批流程
 * 作者姓名: chenshijie
 * 创建时间: 2020/08/29 22:25
 ******************************/
@Service
public class ChangeProcessServiceImpl implements IChangeProcessService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ChangeProcessServiceImpl.class);

    private static final String ACTIVITY_NAME_010 = "010_需求人提交年度采购需求";

    private static final String ACTIVITY_NAME_020 = "020_队办经理审批";

    private static final String ACTIVITY_NAME_030 = "030_计划协调员审批";

    private static final String ACTIVITY_NAME_040 = "040_调试采购主管审批";

    @Autowired
    IBpmCenterService bpmCenterService;

    @Autowired
    ICudFileService cudFileService;

    @Autowired
    ChangeProcessApplyMapper changeProcessApplyMapper;

    @Autowired
    ChangeProcessItemMapper changeProcessItemMapper;

//    @Autowired
//    PurchaseContractItemMapper purchaseContractItemMapper;

    @Autowired
    ChangeProcessAuditMapper changeProcessAuditMapper;

    @Autowired
    CurrentUser currentUser;

    @Autowired
    private IPurchaseContractItemService purchaseContractItemService;

    @Autowired
    private ViewChangeDemandMapper viewChangeDemandMapper;

    @Autowired
    ContractProcessItemMapper contractProcessItemMapper;

    /**********************************
     * 用途说明: 新建年度需求变更审批流程
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public ApiResult insertContract(String params) throws Exception {
        Map map = JSONObject.parseObject(params);

        map.put("folio","年度需求变更审批流程-" +
                new SimpleDateFormat("yyyyMMdd").format(new Date()));

        Map contractMap = (Map) map.get("win");

        ChangeProcessApply changeProcessApply = (ChangeProcessApply) BpmUtil.mapToObjectByJson(contractMap, ChangeProcessApply.class);

        changeProcessApply.setProcInstId("0");

        //判断是否为保存草稿
        if (!StringUtils.isEmpty(map.get("isSaveDraft"))) {
            //先处理业务
            modifyApplyInfo(changeProcessApply);
            //设置流程实例相关的列表ID  可用  针对流程的formInstID
            map.put("appFormId", changeProcessApply.getId());
            //保存草稿  假如从草稿修改过来，isModifyDraft为Y
            if (StringUtils.isEmpty(map.get("isModifyDraft"))) {
                return bpmCenterService.addDraft(map);
            }

            return ApiResult.success() ;
        } else {
            //先处理业务
            modifyApplyInfo(changeProcessApply);
            //设置流程实例相关的列表ID  可用  针对流程的formInstID
            map.put("appFormId", changeProcessApply.getId());
            //启动流程
            return bpmCenterService.startProcess(map);
        }
    }

    private void modifyApplyInfo(ChangeProcessApply changeProcessApply) {
        // 根据id判断之前是否已经保存过数据,有则更新，无则插入
        if (StringUtil.isNullOrSpace(changeProcessApply.getId())) {
            changeProcessApply.setId(IDHelper.uuid());
            changeProcessApply.setCreateTime(new Date());
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            changeProcessApply.setCreateUser(userinfo.getUserId());
            changeProcessApply.setCreateUserName(userinfo.getUserName());
            changeProcessApplyMapper.insert(changeProcessApply);
            insertItem(changeProcessApply);
        } else {
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            changeProcessApply.setLastUpdateUser(userinfo.getUserId());
            changeProcessApply.setLastUpdateUserName(userinfo.getUserName());
            changeProcessApply.setLastUpdateTime(new Date());
            changeProcessApplyMapper.updateById(changeProcessApply);

//            ChangeProcessItemExample changeProcessItemExample = new ChangeProcessItemExample();
//            changeProcessItemExample.createCriteria().andApplyIdEqualTo(changeProcessApply.getId());
//            changeProcessItemMapper.deleteByExample(changeProcessItemExample);

            QueryWrapper<ChangeProcessItem> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("apply_id", changeProcessApply.getId());
            changeProcessItemMapper.delete(queryWrapper);
            insertItem(changeProcessApply);
        }

    }

    private void insertItem(ChangeProcessApply changeProcessApply) {
        for (ViewChangeDemand item : changeProcessApply.getChangeProcessItemList()) {
            ChangeProcessItem changeProcessItem = new ChangeProcessItem();
            changeProcessItem.setItemId(item.getId());
            changeProcessItem.setId(IDHelper.uuid());
            changeProcessItem.setApplyId(changeProcessApply.getId());
            changeProcessItem.setCurrency(item.getCurrency());
            changeProcessItem.setEstimateAmount(item.getEstimateAmount());
            changeProcessItem.setPlannedCompletionTime(item.getPlannedCompletionTime());
            changeProcessItem.setRequiredArrivalTime(item.getRequiredArrivalTime());
            changeProcessItemMapper.insert(changeProcessItem);
        }
    }

    /**********************************
     * 用途说明: 获取环节业务数据
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public Object getActivityBusinessInfo(ActivityInfoParams activityInfoParams) throws Exception {
        if (ACTIVITY_NAME_010.equals(activityInfoParams.getActivityName())) {
            return getApplyById(activityInfoParams);
        } else if (ACTIVITY_NAME_020.equals(activityInfoParams.getActivityName()) ||
                ACTIVITY_NAME_030.equals(activityInfoParams.getActivityName()) ||
                ACTIVITY_NAME_040.equals(activityInfoParams.getActivityName())) {
            return getProcessAudit(activityInfoParams);
        } else {
            throw new ScpException("activity not found.");
        }
    }

    /**********************************
     * 用途说明: 根据id获取年度需求变更审批流程申请信息
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public ChangeProcessApply getApplyById(ActivityInfoParams activityInfoParams) throws Exception {
        ChangeProcessApply changeProcessApply = null;
        if (!StringUtil.isNullOrSpace(activityInfoParams.getId())) {
            changeProcessApply = changeProcessApplyMapper.selectById(activityInfoParams.getId());
        } else if (!StringUtil.isNullOrSpace(activityInfoParams.getProcInstId())) {
            QueryWrapper<ChangeProcessApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("procInstId",activityInfoParams.getProcInstId());

            List<ChangeProcessApply> changeProcessApplies = changeProcessApplyMapper.selectList(queryWrapper);
            if (changeProcessApplies.size() > 0) {
                changeProcessApply = changeProcessApplies.get(0);
            }
        } else {
            throw new ScpException("params error");
        }

        if (changeProcessApply == null) {
            throw new ScpException("details is missing");
        }

//        QueryWrapper<ChangeProcessItem> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("apply_id", changeProcessApply.getId());
//        List<ChangeProcessItem> changeProcessItems = changeProcessItemMapper.selectList(queryWrapper);
//
//        if (changeProcessItems != null && changeProcessItems.size() > 0) {
//            List<String> itemIds = new ArrayList<>();
//            for (ChangeProcessItem changeProcessItem : changeProcessItems) {
//                itemIds.add(changeProcessItem.getItemId());
//            }
//
//            List<PurchaseContractItem> purchaseContractItems = purchaseContractItemService.loadByIdList(itemIds);
//
//            changeProcessApply.setChangeProcessItemList(purchaseContractItems);
//        }

        QueryWrapper<ViewChangeDemand> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", changeProcessApply.getId());
        List<ViewChangeDemand> viewChangeDemands = viewChangeDemandMapper.selectList(queryWrapper);
        changeProcessApply.setChangeProcessItemList(viewChangeDemands);

        return changeProcessApply;
    }

    /**********************************
     * 用途说明: 根据流程实例id获取审批信息
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public ChangeProcessAudit getProcessAudit(ActivityInfoParams activityInfoParams) throws Exception {
        if (StringUtil.isNullOrSpace(activityInfoParams.getProcInstId())) {
            throw new ScpException("procInstId is missing.");
        }
//        ChangeProcessAuditExample changeProcessAuditExample = new ChangeProcessAuditExample();
//        changeProcessAuditExample.createCriteria().
//                andProcInstIdEqualTo(activityInfoParams.getProcInstId()).
//                andActNameEqualTo(activityInfoParams.getActivityName());
//        List<ChangeProcessAudit> changeProcessAudits = changeProcessAuditMapper.selectByExample(changeProcessAuditExample);

        QueryWrapper<ChangeProcessAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("proc_inst_id", activityInfoParams.getProcInstId()).eq("act_name",activityInfoParams.getActivityName());
        List<ChangeProcessAudit> changeProcessAudits = changeProcessAuditMapper.selectList(queryWrapper);

        if (changeProcessAudits.size() > 0) {
            return changeProcessAudits.get(0);
        }
        return null;
    }

    /**********************************
     * 用途说明: 删除业务数据以及草稿
     * 参数说明 paramsMap
     * 返回值说明:
     ***********************************/
    @Override
    public ApiResult deleteApplyAndMyDraft(Map paramsMap) throws Exception {
        String formId = paramsMap.get("id").toString();
        if (StringUtil.isNullOrSpace(formId)) {
            throw new ScpException("params error");
        }

        changeProcessApplyMapper.selectById(formId);

//        ChangeProcessItemExample changeProcessItemExample = new ChangeProcessItemExample();
//        changeProcessItemExample.createCriteria().andApplyIdEqualTo(formId);
//        changeProcessItemMapper.deleteByExample(changeProcessItemExample);

        QueryWrapper<ChangeProcessItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", formId);
        changeProcessItemMapper.delete(queryWrapper);

        ApiResult apiResult = bpmCenterService.deleteMyDraft(paramsMap);

        return apiResult;
    }

    /**********************************
     * 用途说明: 提交流程
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public ApiResult submitProcess(String params) throws Exception {
        Map map = JSONObject.parseObject(params);
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = map.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }

        // 根据环节名称判断当前处理逻辑
        String act_name = map.get("act_name").toString();
        if (ACTIVITY_NAME_020.equals(act_name) ||
                ACTIVITY_NAME_030.equals(act_name) ||
                ACTIVITY_NAME_040.equals(act_name)) {
            processAudit(map);
        } else {
            throw new ScpException("activity not found.");
        }

        //判断是前进还是后退
        String flag = map.get("deal_answer").toString();
        ApiResult apiResult = null;
        if ("1".equals(flag)) {
            if(ACTIVITY_NAME_040.equals(act_name)) {
                //标记需求为已变更
                String appFormId = map.get("formInstID").toString();

                QueryWrapper<ChangeProcessItem> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("apply_id", appFormId);
                List<ChangeProcessItem> changeProcessItems = changeProcessItemMapper.selectList(queryWrapper);
                for(ChangeProcessItem changeProcessItem: changeProcessItems) {
                    ContractProcessItem contractProcessItem = new ContractProcessItem();
                    contractProcessItem.setId(changeProcessItem.getItemId());
                    contractProcessItem.setIsChange(2);
                    contractProcessItemMapper.updateById(contractProcessItem);
                }
            }
            apiResult = bpmCenterService.submitworklistitem(map);
        } else if ("2".equals(flag)) {
            apiResult = bpmCenterService.rollBackAction(map);
        }
        return apiResult;
    }

    /**********************************
     * 用途说明: 审批
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    public void processAudit(Map map) throws Exception {
// 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = map.get("procInstId").toString();
        String deal_answer = map.get("deal_answer").toString();
        String auditNote = map.get("auditNote").toString();
        String act_name = map.get("act_name").toString();

        //根据procInstId查询业务表是否有数据
//        ChangeProcessAuditExample changeProcessAuditExample = new ChangeProcessAuditExample();
//        changeProcessAuditExample.createCriteria().
//                andProcInstIdEqualTo(procInstId).
//                andActNameEqualTo(act_name);
//        List<ChangeProcessAudit> changeProcessAudits = changeProcessAuditMapper.selectByExample(changeProcessAuditExample);

        QueryWrapper<ChangeProcessAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("proc_inst_id", procInstId).eq("act_name",act_name);
        List<ChangeProcessAudit> changeProcessAudits = changeProcessAuditMapper.selectList(queryWrapper);
        UserInfo userinfo = currentUser.getCurrentUserDetail();
        if (changeProcessAudits.size() > 0) {
            //业务数据存在执行更新操作
            ChangeProcessAudit changeProcessAudit = changeProcessAudits.get(0);
            changeProcessAudit.setLastUpdateUser(userinfo.getUserId());
            changeProcessAudit.setLastUpdateUserName(userinfo.getUserName());
            changeProcessAudit.setLastUpdateTime(new Date());
            changeProcessAudit.setProcInstId(procInstId);
            changeProcessAudit.setDealAnswer(Integer.parseInt(deal_answer));
            changeProcessAudit.setAuditNote(auditNote);
            changeProcessAuditMapper.updateById(changeProcessAudit);

        } else {
            //业务数据不存在执行插入操作
            ChangeProcessAudit changeProcessAudit = new ChangeProcessAudit();
            changeProcessAudit.setCreateUser(userinfo.getUserId());
            changeProcessAudit.setCreateUserName(userinfo.getUserName());
            changeProcessAudit.setCreateTime(new Date());
            changeProcessAudit.setProcInstId(procInstId);
            changeProcessAudit.setActName(act_name);
            changeProcessAudit.setId(IDHelper.uuid());
            changeProcessAudit.setDealAnswer(Integer.parseInt(deal_answer));
            changeProcessAudit.setAuditNote(auditNote);
            changeProcessAuditMapper.insert(changeProcessAudit);
        }
    }
}
